<template>
  <Navbar style="margin-bottom: 40px"></Navbar>
  <div class="container">
    <n-card>
      <h2>接口在线体验</h2>
      <n-space vertical size="large">
        <!-- 接口信息显示 -->
        <div v-if="interfaceInfo">
          <n-space align="center">
            <n-avatar size="80" src="https://via.placeholder.com/80" />
            <div>
              <h3>{{ interfaceInfo.name }}</h3>
              <p>{{ interfaceInfo.description }}</p>
            </div>
          </n-space>
          <n-space align="center">
            <n-tag>{{ interfaceInfo.method }}</n-tag>
            <n-input v-model="parameters.url" placeholder="请求 URL" :disabled="true" />
            <n-button @click="copyUrl">复制URL</n-button>
          </n-space>
        </div>

        <!-- 请求参数输入 -->
        <div v-if="interfaceInfo">
          <h3>请求参数</h3>
          <n-space vertical>
            <!-- 查询参数 -->
            <h4>查询参数</h4>
            <n-table>
              <thead>
              <tr>
                <th>参数名</th>
                <th>参数值</th>
                <th>操作</th>
              </tr>
              </thead>
              <tbody>
              <tr v-for="(param, index) in parameters.queryParams" :key="index">
                <td>
                  <n-input v-model="param.name" />
                </td>
                <td>
                  <n-input v-model="param.value" />
                </td>
                <td>
                  <n-button type="error" @click="deleteQueryParam(index)">删除</n-button>
                </td>
              </tr>
              </tbody>
            </n-table>
            <n-button @click="addQueryParam">添加查询参数</n-button>

            <!-- 请求体 -->
            <h4>请求体</h4>
            <n-space vertical>
              <n-radio-group v-model="bodyType">
                <n-radio-button value="json">JSON</n-radio-button>
                <n-radio-button value="form-data">Form Data</n-radio-button>
              </n-radio-group>
              <div v-if="bodyType === 'json'">
                <n-input type="textarea" v-model="requestBody" placeholder="输入 JSON 请求体" />
                <n-button @click="formatJson">格式化 JSON</n-button>
                <n-button @click="validateJson">验证 JSON</n-button>
              </div>
              <div v-if="bodyType === 'form-data'">
                <div v-for="(file, index) in parameters.files" :key="index">
                  <n-upload
                    v-model:file-list="file.list"
                    :on-before-upload="() => false"
                  >
                    <n-button>上传文件</n-button>
                  </n-upload>
                  <n-input v-model="file.value" :placeholder="file.name" />
                </div>
                <n-button @click="addFileParam">添加文件参数</n-button>
              </div>
            </n-space>
          </n-space>
        </div>

        <!-- 发送请求按钮 -->
        <n-button type="primary" @click="sendRequest">发送请求</n-button>

        <!-- 响应显示 -->
        <div v-if="response">
          <h3>响应结果</h3>
          <n-code :code="response" language="json" />
        </div>

        <!-- 请求历史记录 -->
        <div>
          <h3>请求历史</h3>
          <n-list>
            <n-list-item v-for="(history, index) in historyList" :key="index">
              <n-space>
                <span>{{ history.url }}</span>
                <n-button @click="viewHistory(index)">查看</n-button>
              </n-space>
            </n-list-item>
          </n-list>
        </div>

        <!-- 错误信息显示 -->
        <div v-if="error">
          <n-alert type="error" :closable="false">
            {{ error }}
          </n-alert>
        </div>
      </n-space>
    </n-card>
  </div>
</template>

<script>
import { ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import {
  NButton, NCard, NCode, NInput, NList, NListItem, NSpace, NAlert, NTag, NRadioGroup, NRadioButton, NUpload, NAvatar, useMessage
} from 'naive-ui'
import axios from 'axios'
import Navbar from '@/components/Navbar.vue'
import apiClient from '@/api/axios.ts'

export default {
  components: {
    Navbar,
    NButton,
    NCard,
    NCode,
    NInput,
    NList,
    NListItem,
    NSpace,
    NAlert,
    NTag,
    NRadioGroup,
    NRadioButton,
    NUpload,
    NAvatar
  },
  setup() {
    const route = useRoute()
    const interfaceId = route.params.interfaceId
    console.log("接口在线调用页面加载中~，读取的接口id:" + interfaceId)

    const interfaceInfo = ref(null)
    const parameters = ref({
      url: '',
      queryParams: [],
      files: []
    })
    const requestBody = ref('')
    const bodyType = ref('json')
    const response = ref(null)
    const error = ref(null)
    const historyList = ref([])
    const message = useMessage()

    const fetchInterfaceInfo = async () => {
      try {
        const res = await apiClient.get(`/interfaceInfo/get?id=${interfaceId}`)
        interfaceInfo.value = res.data.data
        parameters.value.url = interfaceInfo.value.url
        parameters.value.queryParams = [] // 初始化查询参数列表
        parameters.value.files = [] // 初始化文件参数列表
      } catch (err) {
        error.value = '获取接口信息失败'
      }
    }

    onMounted(() => {
      fetchInterfaceInfo()
    })

    const addQueryParam = () => {
      parameters.value.queryParams.push({ name: '', value: '' })
    }

    const deleteQueryParam = (index) => {
      parameters.value.queryParams.splice(index, 1)
    }

    const addFileParam = () => {
      parameters.value.files.push({ name: '', list: [], value: '' })
    }

    const copyUrl = async () => {
      try {
        await navigator.clipboard.writeText(parameters.value.url)
        message.success('URL 已复制到剪贴板')
      } catch (err) {
        message.error('复制 URL 失败')
      }
    }

    const formatJson = () => {
      try {
        requestBody.value = JSON.stringify(JSON.parse(requestBody.value), null, 2)
        message.success('JSON 格式化成功')
      } catch (err) {
        message.error('JSON 格式化失败')
      }
    }

    const validateJson = () => {
      try {
        JSON.parse(requestBody.value)
        message.success('JSON 验证成功')
      } catch (err) {
        message.error('JSON 验证失败')
      }
    }

    const sendRequest = async () => {
      error.value = null
      response.value = null
      const url = parameters.value.url
      const queryParams = parameters.value.queryParams.reduce((acc, param) => {
        acc[param.name] = param.value
        return acc
      }, {})
      const formData = new FormData()

      if (bodyType.value === 'json') {
        formData.append('body', requestBody.value)
      } else if (bodyType.value === 'form-data') {
        parameters.value.files.forEach(file => {
          if (file.list.length > 0) {
            formData.append(file.name, file.list[0])
          }
          formData.append(file.name, file.value)
        })
      }

      try {
        const res = await axios.post(url, formData, {
          params: queryParams,
          headers: {
            'Content-Type': bodyType.value === 'json' ? 'application/json' : 'multipart/form-data'
          }
        })
        response.value = res.data
        historyList.value.push({ url, queryParams, requestBody: requestBody.value, response: res.data })
      } catch (err) {
        error.value = err.message
      }
    }

    const viewHistory = (index) => {
      const history = historyList.value[index]
      parameters.value.url = history.url
      parameters.value.queryParams = Object.keys(history.queryParams).map((key) => ({
        name: key,
        value: history.queryParams[key]
      }))
      requestBody.value = history.requestBody
      response.value = history.response
    }

    return {
      interfaceInfo,
      parameters,
      requestBody,
      bodyType,
      response,
      error,
      historyList,
      addQueryParam,
      deleteQueryParam,
      addFileParam,
      copyUrl,
      formatJson,
      validateJson,
      sendRequest,
      viewHistory
    }
  }
}
</script>

<style scoped>
.container {
  max-width: 800px;
  margin: 0 auto;
  padding: 2rem;
}
</style>
